package com.zx.system.block.listener;

import com.zx.core.constant.CacheConstants;
import com.zx.redis.block.service.RedisBlockService;
import com.zx.system.block.event.DictTypeChangeEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * 字典类型缓存清理监听器
 * 监听字典类型变更事件，清理相关缓存
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class DictTypeCacheEvictListener {

    private final RedisBlockService redisBlockService;

    /**
     * 处理字典类型变更事件
     * 当收到字典类型变更事件时，清理相关缓存
     *
     * @param event 字典类型变更事件
     */
    @EventListener
    public void handleDictTypeChangeEvent(DictTypeChangeEvent event) {
        try {
            log.info("收到字典类型变更事件: dictType={}, operation={}", event.getDictType(), event.getOperation());

            // 清理所有字典类型的VO缓存
            String allDictTypesCacheKey = CacheConstants.DICT_TYPE_KEY + "enable_list";
            redisBlockService.deleteObject(allDictTypesCacheKey);
            log.info("已清理所有字典类型的VO缓存");

            // 清理所有字典类型的DTO缓存
            String allDictTypesDTOCacheKey = CacheConstants.DICT_TYPE_KEY + "enable_list_dto";
            redisBlockService.deleteObject(allDictTypesDTOCacheKey);
            log.info("已清理所有字典类型的DTO缓存");

            // 清理所有字典类型的基础数据缓存（VO和DTO共享的基础数据）
            String allDictTypesBaseCacheKey = CacheConstants.DICT_TYPE_KEY + "base_enable_list";
            redisBlockService.deleteObject(allDictTypesBaseCacheKey);
            log.info("已清理所有字典类型的基础数据缓存");
        } catch (Exception e) {
            log.error("处理字典类型变更事件时发生错误", e);
        }
    }

    /**
     * 清空所有字典类型缓存
     */
    @SuppressWarnings("unchecked")
    public void clearAllDictTypeCache() {
        try {
            // 使用scan命令查找所有匹配的缓存键
            Set<String> keys = (Set<String>) redisBlockService.redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
                Set<String> result = new HashSet<>();
                Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions()
                        .match(CacheConstants.DICT_TYPE_KEY + "*")
                        .count(1000)
                        .build());

                while (cursor.hasNext()) {
                    result.add(new String(cursor.next()));
                }
                cursor.close();
                return result;
            });

            // 删除匹配的缓存键
            if (!CollectionUtils.isEmpty(keys)) {
                redisBlockService.deleteObject(keys);
                log.info("已清理{}个字典类型缓存键", keys.size());
            }
        } catch (Exception e) {
            log.error("清空所有字典类型缓存时发生错误", e);
        }
    }
}